package com.ld.common.service;

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;

import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;

import org.springframework.stereotype.Service;

import com.ld.admin.model.affix.AffixModel;
import com.ld.admin.model.system.SystemUser;
import com.ld.common.config.web.LdStaticParams;
import com.ld.shieldsb.common.core.model.PropertiesModel;
import com.ld.shieldsb.common.core.model.Result;
import com.ld.shieldsb.common.core.util.StringUtils;
import com.ld.shieldsb.common.web.BasicService;
import com.ld.shieldsb.common.web.util.Web;

/**
 * 项目中的基础service，继承自BasicService，做一些扩展
 * 
 * @ClassName ProjectBasicService
 * @author <a href="mailto:donggongai@126.com" target="_blank">吕凯</a>
 * @date 2019年4月22日 下午5:24:39
 *
 */
@Service
public class ProjectBasicService extends BasicService {

    public void init() {
        userCls = SystemUser.class; // 覆盖用户类
    }

    /**
     * 批量置顶
     * 
     * @Title setZd
     * @author 吕凯
     * @date 2019年4月24日 上午9:23:20
     * @param classOfT
     * @param idsArray
     * @param zd
     * @return Result
     */
    public <T> Result setZd1(Class<T> classOfT, String[] idsArray, int zdValue) {
        String tableName = getBaseDAO().getTableName(classOfT);
        String sql = "update " + tableName + " set zd = ? where id = ?";
        Object[][] params = new Object[idsArray.length][2];
        String operateName = "批量取消置顶";
        if (zdValue == 1) {
            operateName = "批量置顶";
        }
        int i = 0;
        for (String id : idsArray) {
            params[i][0] = zdValue;
            params[i][1] = id;
            i++;
        }
        boolean flag = getBaseDAO().batchUpdate(sql, params) >= 0;
        if (flag) {
            return Web.Response.success(operateName + "成功！（" + idsArray.length + "条）");
        } else {
            return Web.Response.error(operateName + "失败！");
        }
    }

    /**
     * 批量显示、隐藏
     * 
     * @Title setShow
     * @author 吕凯
     * @date 2019年4月24日 上午9:23:35
     * @param classOfT
     * @param idsArray
     * @param showValue
     * @return Result
     */
    public <T> Result setShow(Class<T> classOfT, String[] idsArray, int showValue) {
        String tableName = getBaseDAO().getTableName(classOfT);
        String sql = "update " + tableName + " set isShow = ? where id = ?";
        Object[][] params = new Object[idsArray.length][2];
        String operateName = "批量隐藏";
        if (showValue == 1) {
            operateName = "批量显示";
        }
        int i = 0;
        for (String id : idsArray) {
            params[i][0] = showValue;
            params[i][1] = id;
            i++;
        }
        boolean flag = getBaseDAO().batchUpdate(sql, params) >= 0;
        if (flag) {
            return Web.Response.success(operateName + "操作成功！（" + idsArray.length + "条）");
        } else {
            return Web.Response.error(operateName + "操作失败！");
        }
    }

    /**
     * 保存附件
     * 
     * @Title saveAffixModel
     * @author 吕凯
     * @date 2019年4月25日 上午9:41:59
     * @param name
     * @param path
     * @return AffixModel
     */
    public AffixModel saveAffixModel(AffixModel affixModel) {
        affixModel.setQuote(0);
        getBaseDAO().save(affixModel);
        return affixModel;
    }

    /**
     * 判断附件是否存在
     */
    public Result isExitDownFile() {
        long id = getLong("id");
        if (id != 0) {
            AffixModel affixMd = getBaseDAO().findById(AffixModel.class, id);
            if (affixMd != null && (affixMd.getAffixType() == null || affixMd.getAffixType() == LdStaticParams.ATTFIX.ATTFIX_ONLINE)) {
                if (affixMd != null && checkFileExist(affixMd.getPath())) {
                    return Web.Response.success("");
                } else {
                    return Web.Response.error("下载失败,文件已经不存在！");
                }
            } else {
                if (affixMd != null && checkLocalFileExist(affixMd.getPath())) {
                    return Web.Response.success("");
                } else {
                    return Web.Response.error("下载失败,文件已经不存在！");
                }
            }
        }
        return Web.Response.error("未检测到文件，如已上传文件，请保存后重试。");
    }

    /**
     * 判断服务器文件是否存在
     *
     * @author 张和祥
     * @date 2018年3月30日
     * @param path
     * @return
     */
    private boolean checkFileExist(String path) {
        try {
            String imageHost = PropertiesModel.CONFIG.getString("uploadImageHost");
            path = path.replaceAll(imageHost, "");
            URL url = new URL(imageHost + path);
            HttpURLConnection urlcon2 = (HttpURLConnection) url.openConnection();
            String message = urlcon2.getHeaderField(0);
            if (StringUtils.isNotEmpty(message) && message.indexOf("404") < 0) {
                return true;
            }
        } catch (Exception e) {
        }
        return false;
    }

    /**
     * 判断文件是否存在
     *
     * @author 张和祥
     * @date 2018年3月30日
     * @param filePath
     * @return
     */
    private boolean checkLocalFileExist(String filePath) {
        // 服务器绝对路径
        String servletPath = request.getServletContext().getRealPath("/");
        String path = servletPath + filePath;
        File file = new File(path);
        return file.exists();
    }

    // **
    // 本地附件下载
    // *
    public void downloadLocalAtt(String downFileName, String remoteFilePath, HttpServletResponse response) {
        // 服务器绝对路径
        String servletPath = request.getServletContext().getRealPath("/");
        String filePath = remoteFilePath;
        String path = servletPath + filePath;
        File file = new File(path);
        String fileName = file.getName();
        response.setContentType("multipart/form-data");

        OutputStream fOut = null;
        InputStream inputStream;
        BufferedInputStream bufferedInputStream;
        try {
            fOut = response.getOutputStream();
            response.setHeader("content-Disposition", "attachment;filename=" + URLEncoder.encode(fileName, "utf-8"));
            inputStream = new FileInputStream(file);
            bufferedInputStream = new BufferedInputStream(inputStream, 1024 * 100);
            int read;
            byte[] bufferArea = new byte[1024 * 100];
            while ((read = bufferedInputStream.read(bufferArea, 0, 1024 * 100)) != -1) {
                fOut.write(bufferArea, 0, read);
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if (fOut != null) {
                    fOut.flush();
                }
                if (fOut != null) {
                    fOut.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 附件下载
     */
    public void downloadAtt() throws ServletException, IOException {
        long id = getLong("id");
        AffixModel affixMd = getBaseDAO().findById(AffixModel.class, id);
        if (affixMd.getAffixType() == LdStaticParams.ATTFIX.ATTFIX_ONLINE) {
            downloadAttFile(affixMd.getName(), affixMd.getPath(), response);
        } else if (affixMd.getAffixType() == LdStaticParams.ATTFIX.ATTFIX_LOCAL) {
            downloadLocalAtt(affixMd.getName(), affixMd.getPath(), response);
        }
    }

    /**
     * 从服务器上下载文件
     *
     * @author 张和祥
     * @date 2018年3月30日
     * @param downFileName
     * @param remoteFilePath
     * @param response
     * @return
     * @throws IOException
     */
    public boolean downloadAttFile(String downFileName, String remoteFilePath, HttpServletResponse response) throws IOException {
        String imageHost = PropertiesModel.CONFIG.getString("uploadImageHost");
        URL urlfile = null;
        HttpURLConnection httpUrl = null;
        remoteFilePath = remoteFilePath.replaceAll(imageHost, "");
        urlfile = new URL(imageHost + remoteFilePath);
        httpUrl = (HttpURLConnection) urlfile.openConnection();
        httpUrl.connect();

        // 如果文件名没有扩展名，则根据路径添加
        if (!downFileName.contains(".")) {
            downFileName += remoteFilePath.substring(remoteFilePath.lastIndexOf("/"), remoteFilePath.lastIndexOf("."));
        }
        response.reset();
        response.setContentType("APPLICATION/OCTET-STREAM");
        response.setHeader("Content-Disposition",
                "attachment; filename=\"" + new String(downFileName.getBytes("GBK"), "iso-8859-1") + "\"");
        ServletOutputStream out = response.getOutputStream();
        InputStream in = httpUrl.getInputStream();
        BufferedInputStream bufferStream = null;
        try {
            bufferStream = new BufferedInputStream(in, 1024 * 100);// 输入缓冲流
            int read = 0;
            byte[] bufferArea = new byte[1024 * 100];// 读写缓冲区

            // 在任何情况下，b[0] 到 b[off] 的元素以及 b[off+len] 到 b[b.length-1] 的元素都不会受到影响。这个是官方API给出的read方法说明，经典！
            while ((read = bufferStream.read(bufferArea, 0, 1024 * 100)) != -1) {
                out.write(bufferArea, 0, read);
            }
            return true;
        } catch (Exception e) {
            log.warn("文件下载出错！", e);
            return false;
        } finally {
            if (in != null) {
                try {
                    in.close();
                } catch (Exception e) {
                }
            }
            if (out != null) {
                try {
                    out.close();
                } catch (Exception e) {
                }
            }
        }
    }

}
